home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 2
/
United Public Domain Gold 2.iso
/
utilities
/
pu672.dms
/
pu672.adf
/
d64.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-09
|
10KB
|
291 lines
/********************************\
* >>> DATASETTE 64 <<< *
*--------------------------------*
* ©1993 by ARTSOFT Productions *
* Holger Schemel *
* Sennehof 28 *
* 4800 Bielefeld 12 *
* Tel.: (0521) 493245 *
*--------------------------------*
* LAST UPDATE: 27/02/93 *
\********************************/
/************************************************************\
* >>> Programm zum Einlesen von C64-Datasettenprogrammen <<< *
*------------------------------------------------------------*
* Programm konvertiert C64-Programme, die im TURBO TAPE 64 - *
* Format auf Magnetkassetten gespeichert sind. Um diese auf *
* C64-Emulatoren wie "TheA64Package" oder "The 64 Emulator" *
* verwenden zu können, wenn zur Konvertierung kein C64, ge- *
* schweige denn eine Datasette, mehr zur Verfügung steht, *
* muß das Programm zunächst mit einem Kassettenrecorder bzw. *
* einem Tapedeck sowie einem handelsüblichen Sounddigitizer *
* mit maximaler Samplefrequenz (über 40 kHz) digitalisiert *
* werden (z.B. mit Audiomaster). Der Anfang des Samples muß *
* alsdann maximal vergrößert (Audiomaster: 599 Bytes) werden *
* und der Anfang mit 'Cut' soweit abgeschnitten werden, daß *
* sowohl das anfängliche Bandrauschen als auch Tonschwankun- *
* gen (Welle liegt kurzzeitig völlig über oder unter der *
* Mittellinie) vollständig beseitigt sind. Vom Anfang kann *
* ruhig ein Teil des Synchronisationssignales fehlen. Fängt *
* nun das Sample mit einer Folge von sieben kleineren und *
* einer größeren Welle an, kann es abgespeichert und mit dem *
* Programm 'Datasette64' behandelt werden. *
*------------------------------------------------------------*
* Aufbau einer TurboTape64-Datei: *
* """"""""""""""""""""""""""""""" *
* 1. Synchonisation: *
* - 5 mal (246 mal Byte 2) *
* - Countdownbytes 9,8,7,6,5,4,3,2,1 *
* 2. Vorspann: *
* - Sekundäradresse 1 *
* - Low- und Highbyte der Startadresse *
* - Low- und Highbyte der Endadresse *
* - Füllbyte (0) *
* - Dateiname *
* - Rest wird auf 193 Zeichen mit SPACE aufgefüllt *
* 3. Synchonisation: *
* - 2 mal (246 mal Byte 2) *
* - Countdownbytes 9,8,7,6,5,4,3,2,1 *
* - Null-Byte *
* 4. Daten *
* 5. Prüfsumme: EXOR aller Datenbytes (255 mal) *
* *
*------------------------------------------------------------*
* Um sich das manuelle Entfernen des einleitenden Bandrau- *
* schens zu ersparen, empfiehlt es sich, das Bandlaufwerk *
* einige Umdrehungen vor Beginn der Aufzeichnung zu starten *
* (wobei sich der Bandlauf stabilisieren kann) und den Digi- *
* talisiervorgang zu beginnen, wenn der Synchronisationston *
* ertönt. Der Ton bzw. das Signal ist lang genug, um vorne *
* etwas verkürzt werden zu können. *
*------------------------------------------------------------*
* Erhält man die Meldung "Prüfsumme OK!", so wurde die Datei *
* vollständig korrekt gelesen. Die Meldung "Prüfsummenfeh- *
* ler" kann zwei Gründe haben: *
* - Ein oder mehrere Bits wurden falsch erkannt *
* - Ein oder mehrere Bits fehlen oder sind zuviel *
* Während der erste Fall nur ein falsches Byte nach sich *
* zieht, führt der zweite zu einem bitweise verschobenen *
* Programm, das ab der Fehlerstelle unbrauchbar ist. Meist *
* gibt das Programm dann Wellenlängenabweichungsfehler aus, *
* die oftmals von Hand korrigiert werden können, da die Po- *
* sition des Fehlers in der Sampledatei genannt wird. *
\************************************************************/
#include <exec/memory.h>
#include <libraries/dos.h>
extern VOID *Open(), *AllocMem();
extern LONG Read(), Seek(), Write();
extern VOID Chk_Abort();
extern WORD Enable_Abort;
UBYTE *Lower2Upper();
UBYTE ScanBit();
UBYTE ScanByte();
#define ENDOFFILE (ptr>=max)
#define SCANWHILE(cond) while(ptr<max && (cond))
struct DatasetteFileHeader
{
UBYTE FileAddress2;
UBYTE startlow;
UBYTE starthigh;
UBYTE endlow;
UBYTE endhigh;
UBYTE filler;
UBYTE filename[187];
} DSHeader;
BYTE dbyte,check;
BYTE synctab[100],synccnt,hisync,losync,sync,halfsync,doubsync;
BYTE *ptr,*max,*fptr,*hptr,*FileBuf1=0,*FileBuf2=0;
UWORD *file1=0,*file2=0;
ULONG len1,len2,FileLen1,FileLen2;
LONG i;
main(argc,argv) /*------------ HAUPTPROGRAMM ------------*/
WORD argc;
BYTE *argv[];
{
if (argc<3 || *argv[1]=='?')
CloseAll("Usage: Datasette64 <tape file> <disk file> [<sync>]");
printf("SEARCHING FOR %s\n",Lower2Upper(argv[1]));
if (!(file1=Open(argv[1],MODE_OLDFILE)))
CloseAll("?FILE NOT FOUND ERROR");
Seek(file1,0L,OFFSET_END);
FileLen1=Seek(file1,0L,OFFSET_BEGINNING);
printf("LOADING\n");
if (!(ptr=FileBuf1=AllocMem(FileLen1,MEMF_PUBLIC)))
CloseAll("?OUT OF MEMORY ERROR");
len1=Read(file1,FileBuf1,FileLen1);
max=FileBuf1+(BYTE *)len1;
Close(file1); file1=0;
Chk_Abort();
if (Equal(ptr,"FORM")) /* IFF-Datei? */
{
SCANWHILE(!Equal(ptr,"BODY")) ptr++;
if (!ENDOFFILE)
{
ptr+=4;
max=ptr+(BYTE *)(*(ULONG *)ptr)+4L;
ptr+=4;
}
else ptr=FileBuf1;
}
SCANWHILE(*ptr>=0) ptr++; /* Erste vollständige positive */
SCANWHILE(*ptr< 0) ptr++; /* Zahlenreihe suchen */
synccnt=0;
SCANWHILE(synccnt<100) /* Wellenlängen 0/1-Bits ermitteln */
{
synctab[synccnt]=0;
SCANWHILE(*ptr>=0) { synctab[synccnt]++; ptr++; }
SCANWHILE(*ptr< 0) { synctab[synccnt]++; ptr++; }
synccnt++;
}
hisync=losync=synctab[0];
for(i=1;i<synccnt;i++)
{
if (synctab[i]>hisync) hisync=synctab[i];
if (synctab[i]<losync) losync=synctab[i];
}
sync=(hisync+losync)/2; /* Vergleichswert: "0"<sync<"1" */
if (argc==4)
{
printf("Ermittelter Sync-Wert: %d\n",sync);
if (*argv[3]!='?') sync=atoi(argv[3]);
printf("-->Sync: <%d>>> %d <<<%d>\n",losync,sync,hisync);
}
halfsync=sync-2*(sync-losync);
doubsync=sync+2*(hisync-sync);
SCANWHILE(!ScanBit()); /* Synchronisationsanfang suchen: */
ScanBit(); /* ?-mal Byte 2 = %00000010 */
SkipSync(); /* Erste Synchronisation überspringen */
hptr=(BYTE *)&DSHeader;
for(i=0;i<193;i++) *hptr++=ScanByte();
printf("-->Header:\n");
printf(" - Sekundäradresse: %d\n",DSHeader.FileAddress2);
printf(" - Startadresse LO: %d\n",DSHeader.startlow);
printf(" - Startadresse HI: %d\n",DSHeader.starthigh);
printf(" - Endadresse LO: %d\n",DSHeader.endlow);
printf(" - Endadresse HI: %d\n",DSHeader.endhigh);
dbyte=DSHeader.filename[40];
DSHeader.filename[40]=0;
printf(" - Dateiname : %s\n",DSHeader.filename);
DSHeader.filename[40]=dbyte;
SkipSync(); /* Zweite Synchronisation überspringen */
if (ScanByte()) CloseAll("?LOAD ERROR");
len2=DSHeader.endhigh*256+DSHeader.endlow;
len2-=DSHeader.starthigh*256+DSHeader.startlow;
FileLen2=len2+2L;
if (!(fptr=FileBuf2=AllocMem(FileLen2,MEMF_PUBLIC)))
CloseAll("?OUT OF MEMORY ERROR");
*fptr++=0x01;
*fptr++=0x08;
check=0;
SCANWHILE(len2--) check^=(*fptr++=(BYTE)ScanByte());
if (ENDOFFILE) CloseAll("?OUT OF DATA ERROR");
if (check==ScanByte()) printf("-->Prüfsumme OK!\n");
else printf("-->Prüfsummenfehler!\n");
if (!(file2=Open(argv[2],MODE_NEWFILE)))
CloseAll("?OPEN ERROR");
printf("SAVING\n");
if (Write(file2,FileBuf2,FileLen2)<0)
CloseAll("?WRITE ERROR");
Close(file2); file2=0;
CloseAll(0L);
}
UBYTE *Lower2Upper(str)
UBYTE *str;
{
static UBYTE up[40];
register BYTE z;
for(z=0;*str && z<40;z++,str++) up[z]=toupper(*str);
return(up);
}
Equal(p,s)
UBYTE *p,*s;
{
UBYTE *sp=s;
WORD rc=1;
while(*s) if(*p++!=*s++) rc=0;
return(rc);
}
UBYTE ScanBit()
{
register WORD scnt=0;
static WORD cnt=0;
if (cnt++>25) { Chk_Abort(); cnt=0; }
SCANWHILE(*ptr>=0) { scnt++; ptr++; }
SCANWHILE(*ptr< 0) { scnt++; ptr++; }
if (scnt<halfsync || scnt>doubsync)
printf("-->Wellenlängeninkonsistenz in Byte %ld\n",(LONG)ptr-FileBuf1);
return(scnt>sync);
}
UBYTE ScanByte()
{
register UBYTE i,sbyte=0;
for(i=0;i<8;i++)
{
sbyte<<=1;
sbyte|=ScanBit();
}
return(sbyte);
}
SkipSync()
{
register UBYTE i,sbyte=0;
SCANWHILE((sbyte=ScanByte())==0x02); /* Syncbytes überspringen */
for(i=9;i>0;i--) /* Countdown prüfen */
{
if (i<9) sbyte=ScanByte();
if (sbyte!=i) CloseAll("?LOAD ERROR");
}
}
void _abort()
{
CloseAll("*** User Break");
}
CloseAll(txt)
UBYTE *txt;
{
if (FileBuf1) FreeMem(FileBuf1,FileLen1);
if (FileBuf2) FreeMem(FileBuf2,FileLen2);
if (file1) Close(file1);
if (file2) Close(file2);
if (txt) printf("%s\n",txt);
printf("READY.\n");
exit(txt!=0L);
}